#ifndef _DEBUG_H
#define _DEBUG_H

#include "header.h"

#ifdef _DEBUG

#include <sys/time.h>

#include <string>
#include <iostream>

#include <cxcore.h>


class Timer {
public:

    /** return millisecond */
    static long calcTimeUsed(const Timer &start, const Timer &end) {
        return (end.m_time.tv_sec - start.m_time.tv_sec)*s_THOUSAND +
                (end.m_time.tv_usec - start.m_time.tv_usec) / s_THOUSAND;
    }

    Timer() {
        gettimeofday(&m_time, NULL);
    }

    ~Timer() {
    }

private:
    static const int s_THOUSAND = 1000;
    struct timeval m_time;

};


class Debug {
public:

    enum FileType {
        BINARY,
        TEXT
    };

    static uchar* loadImage(const char *filename, int &width, int &height);

    /** show the image and save it when press ctrl+s */
    static void showImage(const IplImage *image, int wait = 0);

    static void showManyImage(char *title, int nArgs, ...);

    /** show a region of the grey image and save it when press ctrl+s */
    static void showImageData(const uchar *imageData, int iWidth, int x, int y, int pW, int pH, int wait = 0);

    /** show the grey image with width "width" and height "height" and save it when press ctrl+s */
    static void showImageData(const uchar *imageData, int width, int height, int wait = 0) {
        showImageData(imageData, width, 0, 0, width, height, wait);
    }

    /** show the histogram recorded int the float array "data" with width "width" and save it when press ctrl+s */
    static void showNormHistogram(const float *data, int len, int zoom = 1, int wait = 0);

    static void printImageData(const uchar *data, int width, int height);

    static void imageData2bmp(const uchar *imageData, int width, int height, const char *filename);

    static bool isBinarized(const uchar *imageData, int width, int height);

    static bool isBinarized(const IplImage *image);

    static void binarize(uchar *imageData, long size, uchar threshold);

    static void binarize(IplImage *image, uchar threshold);

    static uchar * readImageData(const char *filename, int &width, int &height, FileType type = TEXT);

    static void writeImageData(const char *filename, uchar *imageData, int width, int height, FileType type = TEXT);

    template <typename T>
    static void normAndShowHist(const T *data, int len, int zoom = 1, int wait = 0);

    static void mouseCallback(int event, int x, int y, int flags, void *param);

private:
    Debug(void);
    ~Debug(void);

};

template <typename T>
void Debug::normAndShowHist(const T *data, int len, int zoom, int wait) {
    float *fdata = new float[len];

    float count = 0;
    for (int i = 0; i < len; i++) {
        count += data[i];
    }

    for (int i = 0; i < len; i++) {
        fdata[i] = data[i]*0.1f / count;
    }

    showNormHistogram(fdata, len, zoom, wait);

    delete[] fdata;
}

#endif

#endif
